// PropertyStack.h: interface for the PropertyStack class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PROPERTYSTACK_H__CEEDC02D_73D2_492C_8D4C_BA9BE0AA3DAE__INCLUDED_)
#define AFX_PROPERTYSTACK_H__CEEDC02D_73D2_492C_8D4C_BA9BE0AA3DAE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Map.h"
#include "PropertyVariable.h"
#include "stackInterface.h"
#include "Variable.h"

namespace PropertySystem
{	
	class PropertyStack;
	
	class __declspec( dllexport ) PropertyStackIterator : public PropertyStackInterface::Iterator
	{
	public:
		PropertyStackIterator(PropertyStack* pStack);
		virtual ~PropertyStackIterator(){}
		
	public:
		virtual void Begin();
		virtual void Next();
		
	private:
		POSITION m_pos;
		PropertyStack* m_pStack;
		PropertyVariable* m_pPrevVariable;
	};
	
	class __declspec( dllexport ) PartTypePropertyIterator : public PropertyStackInterface::Iterator
	{
	public:
		PartTypePropertyIterator(PropertyStack* pStack);
		virtual ~PartTypePropertyIterator(){}

	public:
		virtual void Begin();
		virtual void Next();

	private:
		POSITION m_pos;
		PropertyStack* m_pStack;
		PropertyVariable* m_pPrevVariable;
	};

	class __declspec( dllexport ) PropertyStackFilterIterator : public PropertyStackIterator
	{
	public:
		PropertyStackFilterIterator(PropertyStack* pStack, const CStringArray* pTable):PropertyStackIterator(pStack),
			m_pTables(pTable){ASSERT(m_pTables);}
		virtual ~PropertyStackFilterIterator(){}

	public:
		virtual void Begin();
		virtual void Next();

	private:
		void Filter();

	private:
		const CStringArray* m_pTables;
	};

	class __declspec( dllexport ) PropertyStackSavePropertyIterator : public PropertyStackIterator
	{
	public:
		PropertyStackSavePropertyIterator(PropertyStack* pStack):PropertyStackIterator(pStack){
		}
		virtual ~PropertyStackSavePropertyIterator(){
		}
		
	public:
		virtual void Begin();
		virtual void Next();

	private:
		void Filter();
	};
	class __declspec( dllexport ) PropertyStack : public PropertyStackInterface
	{
		friend PropertyStackIterator;
		friend PartTypePropertyIterator;
	public:
		PropertyVariable* GetProperty(const CString& strPropertyName);
		virtual void RemoveAll();
		void AddProperty(PropertyVariable* pVariable);
		PropertyStack();
		virtual ~PropertyStack();
		
	public:
		void RemoveEffect();
		void RegisterEffect();

		virtual void Add(const Index& index, const DataType& pType){
			AddProperty(static_cast<PropertyVariable*>(pType));
		}
		
		virtual DataType Get(const Index& index){
			return GetProperty(index);
		}
		
		virtual DataType Remove(const Index& index){
			PropertyVariable* pVariable = NULL;
			if(m_thePropertys.Lookup(index, pVariable))
			{
				m_thePropertys.RemoveKey(index);
				m_thePartTypeProperties.RemoveKey(index);
				return pVariable;
			}
			return NULL;
		}
		
		virtual Iterator* NewIterator(){
			return new PropertyStackIterator(this);
		}
		
		virtual Iterator* NewPartTypeIterator(){
			return new PartTypePropertyIterator(this);
		}

		virtual Iterator* NewSavePropertyIterator(){
			return new PropertyStackSavePropertyIterator(this);
		}
		
		Iterator* NewFilteriterator(const CStringArray* pstrFilter){
			return new PropertyStackFilterIterator(this, pstrFilter);
		}

		PropertyStack& operator=(PropertyStack& stack);
		PropertyStack& operator+=(PropertyStack& stack);
	private:
		CMap<CString, CString, PropertyVariable*, PropertyVariable*> m_thePropertys;
		CMap<CString, CString, PropertyVariable*, PropertyVariable*> m_thePartTypeProperties;
	};
};
#endif // !defined(AFX_PROPERTYSTACK_H__CEEDC02D_73D2_492C_8D4C_BA9BE0AA3DAE__INCLUDED_)
